package server

import (
	"crypto/subtle"
	"encoding/base64"
	"net/http"
	"strings"

	"gitee.com/Gakusyun/gakusyun-ws/config"
	"gitee.com/Gakusyun/gakusyun-ws/templates"
	"gitee.com/Gakusyun/gakusyun-ws/utils"
)

// SecurityMiddleware 安全中间件，设置安全头
func SecurityMiddleware(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		utils.SetSecurityHeaders(w)
		next(w, r)
	}
}

// LoggingMiddleware 日志中间件
func LoggingMiddleware(logger any, next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 这里可以添加请求日志记录
		next(w, r)
	}
}

// DevInterceptorMiddleware 开发者拦截器中间件
func DevInterceptorMiddleware(cfg *config.Config, next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 统一设置安全头
		utils.SetSecurityHeaders(w)

		// 如果未启用开发者拦截器，直接放行
		if !cfg.DevInterceptorEnabled {
			next(w, r)
			return
		}

		// 检查是否是登录页面请求
		if r.URL.Path == "/dev-login" {
			serveDevLoginPage(w, r, cfg)
			return
		}

		// 检查是否是登录验证请求
		if r.URL.Path == "/dev-auth" && r.Method == "POST" {
			handleDevAuth(w, r, cfg)
			return
		}

		// 检查是否有有效的session cookie
		sessionCookie, err := r.Cookie("dev_session")
		if err == nil && sessionCookie.Value != "" {
			// 验证session
			if validateSession(sessionCookie.Value, cfg) {
				next(w, r)
				return
			}
		}

		// 检查Authorization header (Basic Auth)
		authHeader := r.Header.Get("Authorization")
		if authHeader != "" && strings.HasPrefix(authHeader, "Basic ") {
			// 验证Basic Auth
			if validateBasicAuth(authHeader, cfg) {
				next(w, r)
				return
			}
		}

		// 检查前端存储的token
		if r.Method == "POST" {
			err := r.ParseForm()
			if err == nil {
				token := r.FormValue("dev_token")
				if token != "" && validateToken(token, cfg) {
					// 设置session cookie
					http.SetCookie(w, utils.CreateSessionCookie("dev_session", generateSessionToken(cfg), 3600*24))
					next(w, r)
					return
				}
			}
		}

		// 如果没有有效的认证，重定向到登录页面
		http.Redirect(w, r, "/dev-login", http.StatusFound)
	}
}

// validateBasicAuth 验证HTTP Basic Authentication
func validateBasicAuth(authHeader string, cfg *config.Config) bool {
	// 提取Base64编码的部分
	encoded := strings.TrimPrefix(authHeader, "Basic ")
	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		return false
	}

	// 分离用户名和密码
	parts := strings.SplitN(string(decoded), ":", 2)
	if len(parts) != 2 {
		return false
	}

	username := parts[0]
	password := parts[1]

	// 使用常量时间比较防止时序攻击
	return subtle.ConstantTimeCompare([]byte(username), []byte(cfg.DevUsername)) == 1 &&
		subtle.ConstantTimeCompare([]byte(password), []byte(cfg.DevPassword)) == 1
}

// validateSession 验证session
func validateSession(sessionValue string, cfg *config.Config) bool {
	// 这里简化处理，实际应用中应该使用更安全的session验证
	// 可以检查session的有效性、过期时间等
	expectedSession := generateSessionToken(cfg)
	return subtle.ConstantTimeCompare([]byte(sessionValue), []byte(expectedSession)) == 1
}

// validateToken 验证前端token
func validateToken(token string, cfg *config.Config) bool {
	// 验证前端提交的token是否正确
	expectedToken := base64.StdEncoding.EncodeToString([]byte(cfg.DevUsername + ":" + cfg.DevPassword))
	return subtle.ConstantTimeCompare([]byte(token), []byte(expectedToken)) == 1
}

// generateSessionToken 生成session token
func generateSessionToken(cfg *config.Config) string {
	// 简单的session token生成，实际应用中应该使用更安全的方法
	return base64.StdEncoding.EncodeToString([]byte(cfg.DevUsername + ":" + cfg.DevPassword + ":session"))
}

// serveDevLoginPage 提供开发者登录页面
func serveDevLoginPage(w http.ResponseWriter, _ *http.Request, _ *config.Config) {
	content, err := templates.RenderDevLogin()
	if err != nil {
		utils.ErrorResponse(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "text/html")
	w.Write([]byte(content))
}

// handleDevAuth 处理开发者认证请求
func handleDevAuth(w http.ResponseWriter, r *http.Request, cfg *config.Config) {
	err := r.ParseForm()
	if err != nil {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return
	}

	token := r.FormValue("dev_token")
	if token == "" {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// 验证token
	if validateToken(token, cfg) {
		// 设置session cookie
		http.SetCookie(w, utils.CreateSessionCookie("dev_session", generateSessionToken(cfg), 3600*24))

		// 返回成功响应
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte(`{"success": true}`))
	} else {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
	}
}